﻿using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Navigation;
using com.IronOne.BoardPACWinApp.Common;
using com.IronOne.BoardPACWinApp.Helpers;
using com.IronOne.BoardPACWinApp.Sync;
using com.IronOne.BoardPACWinAppBO.General;
using com.IronOne.BoardPACWinAppService.Auth;
using com.IronOne.BoardPACWinAppUtil.Enums;
using com.IronOne.BoardPACWinAppUtil.Util;
using GalaSoft.MvvmLight.Messaging;
using Windows.UI.Xaml.Controls;
using com.IronOne.BoardPACWinApp.ViewModel.UserControlViewModel;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace com.IronOne.BoardPACWinApp.View.UserControl.SettingPanels
{
    /// <summary>
    ///     An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class SettingSyncManagement
    {
        private InputMessageDialog _dlg;
        private bool _isRefreshRunning;
        private bool _isResetRunning;
        private readonly IAuthService _authService;
        private readonly IDialogService _dialogService;

        public SettingSyncManagement()
        {
            InitializeComponent();
            _authService = new AuthService();
            _dialogService = new DialogService();
        }

        protected override async void HandleMessages(NotificationMessage<MessageDataModel> mdm)
        {
            try
            {
                base.HandleMessages(mdm);
                await BasePage.GetInstance().HandleMessages(mdm);

                if (mdm.Notification.Equals(MessageCodes.SYNC_DATA_DOWNLOAD_SUCCESS) ||
                    mdm.Notification.Equals(MessageCodes.SYNC_SUCCESS))
                {
                    if (_isRefreshRunning)
                    {
                        DisplayRefreshInfo("Synchronization completed");
                        _isRefreshRunning = false;
                    }

                    if (_isResetRunning)
                    {
                        DisplayResetInfo("Reset completed");
                        HideDialog();
                        _isResetRunning = false;
                    }
                }
                if (mdm.Notification.Equals(MessageCodes.SYNC_DATA_DOWNLOAD_FAIL) ||
                    mdm.Notification.Equals(MessageCodes.SYNC_ERROR_STOP))
                {
                    if (_isRefreshRunning)
                    {
                        DisplayRefreshInfo("Synchronization failed");
                        _isRefreshRunning = false;
                    }

                    if (_isResetRunning)
                    {
                        DisplayResetInfo("Reset failed");
                        HideDialog();
                        _isResetRunning = false;
                    }
                }
                if (mdm.Notification.Equals(MessageCodes.IS_ONLINE))
                {
                    var isOnline = (bool) mdm.Content.MessageData;
                    if (!isOnline)
                    {
                        if (_isRefreshRunning)
                        {
                            DisplayRefreshInfo("Synchronization failed due to lost connectivity");
                            _isRefreshRunning = false;
                        }

                        if (_isResetRunning)
                        {
                            DisplayResetInfo("Reset failed due to lost connectivity");
                            HideDialog();
                            _isResetRunning = false;
                        }
                    }
                }
            }
            catch (Exception)
            {
                if (_isRefreshRunning)
                {
                    DisplayRefreshInfo("Synchronization failed");
                    _isRefreshRunning = false;
                }

                if (_isResetRunning)
                {
                    DisplayResetInfo("Reset failed");
                    HideDialog();
                    _isResetRunning = false;
                }
            }
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            try
            {
                base.OnNavigatedTo(e);

                if (Global.UserForceWentOffline || ProfileUserControlViewModel.IsUserInvolved)
                    OfflineTgl.IsOn = true;
                else
                    OfflineTgl.IsOn = false;
            }
            catch (Exception)
            {
            }
        }

        private async void Refresh_Btn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                RefreshBtn.IsEnabled = false;

                await StopSync(true);
                SyncManager.GetInstance().StartSync();

                _isRefreshRunning = true;
                _isResetRunning = false;
            }
            catch (Exception)
            {
                DisplayRefreshInfo("Synchronization failed");
            }
        }

        private async void Reset_Btn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var result1 =
                    await
                        _dialogService.ShowMessageYesNo(
                            "Application will not be responsive during this process. Are you sure you want to continue?",
                            DefaultButtonCommand.No);
                if (!result1) return;

                _dlg = new InputMessageDialog(
                    "Reset operation initiated, Do not close the application until completion", Visibility.Collapsed,
                    Visibility.Collapsed, true);
                _dlg.ShowAsync();

                ResetBtn.IsEnabled = false;

                await StopSync(false);
                var rdm = await _authService.ResetDevice();

                if (rdm.IsError)
                {
                    DisplayResetInfo("Reset failed");
                    HideDialog();
                }

                SyncManager.GetInstance().StartSync();

                _isResetRunning = true;
                _isRefreshRunning = false;
            }
            catch (Exception)
            {
                DisplayResetInfo("Reset failed");
                HideDialog();
            }
        }

        private void DisplayRefreshInfo(string msg)
        {
            try
            {
                RefreshInfoTxt.Text = msg;
                RefreshInfoTxt.Text += " on " + Utility.GetDate(DateTime.Now).ToString(Utility.GetDateTimeFormat());
                RefreshBtn.IsEnabled = true;
            }
            catch (Exception)
            {
            }
        }

        private void DisplayResetInfo(string msg)
        {
            try
            {
                ResetInfoTxt.Text = msg;
                ResetInfoTxt.Text += " on " + Utility.GetDate(DateTime.Now).ToString(Utility.GetDateTimeFormat());
                ResetBtn.IsEnabled = true;
            }
            catch (Exception)
            {
            }
        }

        private void HideDialog()
        {
            try
            {
                if (_dlg == null) return;
                _dlg.HideAsync();
            }
            catch (Exception)
            {
            }
        }

        private async Task<bool> StopSync(bool isRefresh)
        {
            try
            {
                var textblock = isRefresh ? RefreshInfoTxt : ResetInfoTxt;

                textblock.Text = "Initializing...";
                SyncManager.StopSync();

                while (true)
                {
                    await Task.Delay(500);
                    if (!SyncManager.IsSyncStopped())
                    {
                        continue;
                    }
                    break;
                }
                textblock.Text = "Processing...";
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }

        private async void OfflineTgl_Toggled(object sender, RoutedEventArgs e)
        {
            try
            {
                var toggle = sender as ToggleSwitch;
                if (toggle.IsOn) //Offline
                {
                    SyncManager.StopSync();
                    Global.UserForceWentOffline = true;

                    var mdm = new MessageDataModel { MessageData = false };
                    var message = new NotificationMessage<MessageDataModel>(mdm, MessageCodes.IS_ONLINE);
                    Messenger.Default.Send(message);

                    //NOTE: Above message will be ignored from ProfileUserControlViewModel if the "IsUserInvolved" 
                    //assigned before send the above message.
                    ProfileUserControlViewModel.IsUserInvolved = true;

                    OfflineTgl.IsEnabled = false;
                    OfflineTgl.OnContent = "Processing...";
                    while (true)
                    {
                        await Task.Delay(500);
                        if (!SyncManager.IsSyncStopped())
                        {
                            continue;
                        }
                        break;
                    }
                    OfflineTgl.OnContent = "On"; 
                }
                else  //Online
                {
                    Global.UserForceWentOffline = false;
                    ProfileUserControlViewModel.IsUserInvolved = false;
                    await NetworkConnectivityManager.ServerUpCheckOnce();
                    SyncManager.GetInstance().StartSync();
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                OfflineTgl.IsEnabled = true;
            }
        }
    }
}